#!/usr/bin/env node

// docpack - documentation for take-away
// disgusting ... but works for now ...

var path   = require('path')
  , fs     = require('fs')
  , child_process = require('child_process')
  , slide  = require('slide')
  , mkdirp = require('mkdirp')
  , glob   = require('glob')
  , ejs    = require('ejs')
  , less   = require('less')
  , ncp    = require('ncp').ncp
  , view   = require('./lib/view')
  , obj = require('./lib/obj')
  , j      = path.join
  , chain  = slide.chain
  , compiler = require('./lib/compiler')
  ;

var rootd = path.resolve(path.dirname(process.argv[1]), '..')
  , docd  = rootd + '/doc'
  , outd  = rootd + '/build/pages'
  , package = JSON.parse(fs.readFileSync(rootd + '/package.json'))
  , layout = fs.readFileSync(docd + '/layout.ejs').toString()
  ;

var ejs2textile = compiler.compilerSync(ejs.render, 'ejs', {package: package})
  , ejs2html    = compiler.compiler(render_page, 'redcloth', {dst: compiler.dst, outputDir: outd})
  , less2css    = compiler.compiler(less.render, 'less')
  ;

var prepare = [ [ mkdirp, outd ]
              ]
  , tasks   = [ [ ejs2textile, docd + '/README.ejs', rootd + '/README.textile']
              , [ render_pages, docd + '/pages/*.ejs']
              , [ render_build_status_pages ]
              , [ render_stylesheets, docd + '/pages/stylesheets/*.less']
              , [ ncp, docd + '/pages/images', outd + '/images']
              , [ ncp, docd + '/pages/scripts', outd + '/scripts']
              , [ ncp, docd + '/pages/jqplot', outd + '/jqplot']
              ]
              ;

chain( [ [ run_all, prepare]
       , [ run_all, tasks]
       ]
     , function(error) { if (error) console.log(error) }
     );



function render_pages(pattern, cb) {
  glob(pattern, function(error, files) {
    var tasks = files.map(function(f) { 
      var dst = path.join(outd, path.basename(path.basename(f), '.ejs'))
          + '.html';
      return [ejs2html, f, dst] 
    });
    run_all(tasks, cb);
  });
}

function render_stylesheets(pattern, cb) {
  glob(pattern, function(error, files) {
    var tasks = files.map(function(f) { 
      var dst = outd + '/stylesheets/'
          + path.basename(path.basename(f), '.less') + '.css';
      return [less2css, f, dst, {}] 
    });
    run_all(tasks, cb);
  });
}

function render_page(source, options, cb) {
  var metadata = { scripts: [], stylesheets: ['/stylesheets/mdns.css']};
  function layout_page(error, html) {
    metadata.body = html;
    cb(error, ejs.render(layout, obj.union(metadata, view.helpers(metadata, options))))
  }
  var locals = obj.union({package: package}, view.helpers(metadata, options));
  piped_comand('redcloth', ejs.render(source, locals), layout_page);
}

function render_build_status_pages(cb) {
  cb()
}

function piped_comand(comand, input, args, cb) {
  if ( ! cb ) {
    cb = args;
    args = undefined;
  }
  var cmd = child_process.spawn(comand, args)
    , out = ''
    ;
  cmd.stdout.on('data', function(chunk) { out += chunk })
  cmd.stderr.on('data', function(chunk) { console.log(chunk)})
  cmd.on('exit', function(code) {
    if (code) {
      cb(new Error("command '" + command + "' exited with code " + code))
    } else {
      cb(null, out)
    }
  });
  cmd.stdin.write(input);
  cmd.stdin.destroySoon();
  
}


function run_all(tasks, cb) {
  var done_count = 0, first_error;
  function on_done(error) {
    if (error) {
      first_error = error;
      cb(error);
    }
    if ( ! first_error && ++done_count === tasks.length) cb();
  }
  tasks.forEach(function(t) {
    var f = t.shift();
    t.push(on_done)
    f.apply(null, t);
  });
}

// vim: filetype=javascript :
